// src/text_processor.rs
use rayon::prelude::*;
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};

/// 高性能文本处理器
pub struct TextProcessor {
    /// 风险相关词汇字典
    risk_keywords: HashMap<String, f64>,
    /// 防护相关词汇字典
    protection_keywords: HashMap<String, f64>,
}

impl TextProcessor {
    /// 创建新的文本处理器实例
    pub fn new() -> Result<Self, Box<dyn Error>> {
        // 从配置文件加载风险和防护关键词
        let risk_keywords = Self::load_keywords("config/risk_keywords.txt")?;
        let protection_keywords = Self::load_keywords("config/protection_keywords.txt")?;

        Ok(Self {
            risk_keywords,
            protection_keywords,
        })
    }

    /// 加载关键词及其权重
    fn load_keywords(file_path: &str) -> Result<HashMap<String, f64>, Box<dyn Error>> {
        let file = File::open(file_path)?;
        let reader = BufReader::new(file);
        let mut keywords = HashMap::new();

        for line in reader.lines() {
            let line = line?;
            let parts: Vec<&str> = line.split('\t').collect();
            if parts.len() >= 2 {
                let keyword = parts[0].to_string();
                let weight = parts[1].parse::<f64>()?;
                keywords.insert(keyword, weight);
            }
        }

        Ok(keywords)
    }

    /// 并行处理多个文本
    pub fn process_texts(&self, texts: Vec<String>) -> Vec<(f64, f64)> {
        texts.par_iter()
            .map(|text| self.analyze_text(text))
            .collect()
    }

    /// 分析单个文本，返回(风险敞口得分, 防护能力得分)
    pub fn analyze_text(&self, text: &str) -> (f64, f64) {
        let lowercase_text = text.to_lowercase();
        let words: Vec<&str> = lowercase_text.split_whitespace().collect();

        // 计算风险敞口得分
        let risk_score = self.calculate_keyword_score(&words, &self.risk_keywords);

        // 计算防护能力得分
        let protection_score = self.calculate_keyword_score(&words, &self.protection_keywords);

        (risk_score, protection_score)
    }

    /// 根据关键词词典计算得分
    fn calculate_keyword_score(&self, words: &[&str], keywords: &HashMap<String, f64>) -> f64 {
        let mut score = 0.0;

        // 统计关键词出现次数
        let mut keyword_counts = HashMap::new();
        for word in words {
            if keywords.contains_key(*word) {
                *keyword_counts.entry(*word).or_insert(0) += 1;
            }
        }

        // 计算得分
        for (word, count) in keyword_counts.iter() {
            if let Some(weight) = keywords.get(*word) {
                score += *weight * (*count as f64);
            }
        }

        score
    }

    /// 分析否定表达
    pub fn analyze_negation(&self, text: &str) -> Vec<(String, bool)> {
        let lowercase_text = text.to_lowercase();

        // 中文金融特有的否定表达模式
        let negation_patterns = [
            "不足以", "难以", "无法", "不能", "未能",
            "未完全", "不完全", "不确保", "不保证"
        ];

        let sentences: Vec<&str> = lowercase_text.split(['。', '!', '?', ';', '；']).collect();
        let mut results = Vec::new();

        for sentence in sentences {
            let contains_negation = negation_patterns.iter()
                .any(|pattern| sentence.contains(pattern));
            if !sentence.trim().is_empty() {
                results.push((sentence.to_string(), contains_negation));
            }
        }

        results
    }
}

// src/main.rs
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use std::vec::Vec;

mod text_processor;
use text_processor::TextProcessor;

/// 处理一批文本并返回风险和防护得分
#[pyfunction]
fn batch_process_texts(texts: Vec<String>) -> PyResult<Vec<(f64, f64)>> {
    let processor = TextProcessor::new()
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?;

    Ok(processor.process_texts(texts))
}

/// 分析文本中的否定表达
#[pyfunction]
fn analyze_text_negation(text: String) -> PyResult<Vec<(String, bool)>> {
    let processor = TextProcessor::new()
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?;

    Ok(processor.analyze_negation(&text))
}

/// Python模块定义
#[pymodule]
fn text_analysis(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(batch_process_texts, m)?)?;
    m.add_function(wrap_pyfunction!(analyze_text_negation, m)?)?;
    Ok(())
}
